<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <meta name="author" content="隐星魂 (Roy.Sun)">
        
        <link rel="shortcut icon" href="../../../img/favicon.ico">
        <title>工程配置指南 - 玄武操作系统</title>
        <link href="../../../css/bootstrap.min.css" rel="stylesheet">
        <link href="../../../css/font-awesome.min.css" rel="stylesheet">
        <link href="../../../css/base.css" rel="stylesheet">
        <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.3/styles/color-brewer.min.css">

        <script src="../../../js/jquery-1.10.2.min.js" defer></script>
        <script src="../../../js/bootstrap.min.js" defer></script>
        <script src="https://cdn.staticfile.org/highlight.js/10.0.3/highlight.min.js"></script>
        <script>hljs.initHighlightingOnLoad();</script> 
    </head>

    <body>
        <div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
            <div class="container">
                <a class="navbar-brand" href="../../..">玄武操作系统</a>
                <!-- Expander button -->
                <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <!-- Expanded navigation -->
                <div id="navbar-collapse" class="navbar-collapse collapse">
                        <!-- Main navigation -->
                        <ul class="nav navbar-nav">
                            <li class="navitem">
                                <a href="../../.." class="nav-link">主页</a>
                            </li>
                            <li class="navitem">
                                <a href="../../../license/" class="nav-link">开源协议</a>
                            </li>
                            <li class="dropdown active">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">快速开发指南 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">STM32</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../01-Envsetup-Guide/" class="dropdown-item">开发环境搭建指南</a>
</li>
            
<li>
    <a href="./" class="dropdown-item active">工程配置指南</a>
</li>
            
<li>
    <a href="../03-atkh743/" class="dropdown-item">正点原子阿波罗H743开发板上手指南</a>
</li>
            
<li>
    <a href="../04-fk429m/" class="dropdown-item">反客F429核心板上手指南</a>
</li>
            
<li>
    <a href="../05-atkf407core/" class="dropdown-item">正点原子F407核心板上手指南</a>
</li>
            
<li>
    <a href="../06-atkf103core/" class="dropdown-item">正点原子F103核心板上手指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">NXP S32K</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../s32k/01-Envsetup-Guide/" class="dropdown-item">开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../s32k/02-Project-Setup-Guide/" class="dropdown-item">工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">玄武内核模块</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../xwko/01-XuanWuKO-Guide/" class="dropdown-item">上手指南</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">应用手册 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../../UserManual/00-index/" class="dropdown-item">00.目录</a>
</li>
                                    
<li>
    <a href="../../../UserManual/01-brief/" class="dropdown-item">01.简介</a>
</li>
                                    
<li>
    <a href="../../../UserManual/02-Basic-System-Architecture/" class="dropdown-item">02.系统基本架构</a>
</li>
                                    
<li>
    <a href="../../../UserManual/03-Build-System/" class="dropdown-item">03.构建系统</a>
</li>
                                    
<li>
    <a href="../../../UserManual/04-Boot-Flow/" class="dropdown-item">04.启动流程</a>
</li>
                                    
<li>
    <a href="../../../UserManual/05-IRQ/" class="dropdown-item">05.中断控制</a>
</li>
                                    
<li>
    <a href="../../../UserManual/06-SKD/" class="dropdown-item">06.调度器</a>
</li>
                                    
<li>
    <a href="../../../UserManual/07-Thread/" class="dropdown-item">07.线程</a>
</li>
                                    
<li>
    <a href="../../../UserManual/08-SWT/" class="dropdown-item">08.软件定时器</a>
</li>
                                    
<li>
    <a href="../../../UserManual/09-PM/" class="dropdown-item">09.电源管理</a>
</li>
                                    
<li>
    <a href="../../../UserManual/10-Lock/" class="dropdown-item">10.锁</a>
</li>
                                    
<li>
    <a href="../../../UserManual/11-Sync/" class="dropdown-item">11.同步</a>
</li>
                                    
<li>
    <a href="../../../UserManual/12-MM/" class="dropdown-item">12.内存管理</a>
</li>
                                    
<li>
    <a href="../../../UserManual/13-C-Lib/" class="dropdown-item">13.玄武C库</a>
</li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">移植笔记 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../../PortingNote/00-index/" class="dropdown-item">目录</a>
</li>
                                    
<li>
    <a href="../../../PortingNote/01-Porting-Note/" class="dropdown-item">移植笔记</a>
</li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">ARM-Cortex-M</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../../PortingNote/ARM-Cortex-M/01-ARM-Cortex-M-Porting-Note/" class="dropdown-item">架构移植笔记</a>
</li>
            
<li>
    <a href="../../../PortingNote/ARM-Cortex-M/02-STM32-Porting-Note/" class="dropdown-item">STM32</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">规范 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../../Specification/00-index/" class="dropdown-item">目录</a>
</li>
                                    
<li>
    <a href="../../../Specification/01-Git-Commit-Specification/" class="dropdown-item">git-commit规范</a>
</li>
                                    
<li>
    <a href="../../../Specification/02-Version-Branch-Specification/" class="dropdown-item">版本分支规范</a>
</li>
                                </ul>
                            </li>
                        </ul>

                    <ul class="nav navbar-nav ml-auto">
                        <li class="nav-item">
                            <a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
                                <i class="fa fa-search"></i> 搜索
                            </a>
                        </li>
                            <li class="nav-item">
                                <a rel="prev" href="../01-Envsetup-Guide/" class="nav-link">
                                    <i class="fa fa-arrow-left"></i> 上一篇
                                </a>
                            </li>
                            <li class="nav-item">
                                <a rel="next" href="../03-atkh743/" class="nav-link">
                                    下一篇 <i class="fa fa-arrow-right"></i>
                                </a>
                            </li>
                    </ul>
                </div>
            </div>
        </div>

        <div class="container">
            <div class="row">
                    <div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
    <div class="navbar-header">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
            <span class="fa fa-angle-down"></span>
        </button>
    </div>

    
    <div id="toc-collapse" class="navbar-collapse collapse card bg-secondary">
        <ul class="nav flex-column">
            
            <li class="nav-item" data-level="1"><a href="#_1" class="nav-link">工程配置指南</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#1" class="nav-link">1.搭建开发环境</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#2" class="nav-link">2.选择模板</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#3" class="nav-link">3.改名</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#4memory" class="nav-link">4.修改memory区域</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#41ld" class="nav-link">4.1.ld的基本语法</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#5stm32cubemx" class="nav-link">5.STM32CubeMX</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#51stm32cubemx" class="nav-link">5.1.导入STM32CubeMX工程</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#52" class="nav-link">5.2.设置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#53" class="nav-link">5.3.生成源码</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#54" class="nav-link">5.4.集成</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#55" class="nav-link">5.5.编译</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#6stm32cubeide" class="nav-link">6.使用STM32CubeIDE进行开发</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#61eclipse" class="nav-link">6.1.Eclipse设置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#62" class="nav-link">6.2.新建工程</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#63" class="nav-link">6.3.文件编码设置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#64" class="nav-link">6.4.编译设置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#65" class="nav-link">6.5.环境变量设置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#66" class="nav-link">6.6.头文件路径设置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#67" class="nav-link">6.7.调试</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#7" class="nav-link">7.代码启动流程</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#8" class="nav-link">8.使用命令行方式进行开发</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#81" class="nav-link">8.1.编译</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#82" class="nav-link">8.2.调试</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
            
            <li class="nav-item" data-level="1"><a href="#8_1" class="nav-link">8.附录</a>
              <ul class="nav flex-column">
              </ul>
            </li>
        </ul>
    </div>
</div></div>
                    <div class="col-md-9" role="main">

<h1 id="_1">工程配置指南</h1>
<hr />
<p>下面以淘宝上广泛存在的STM32F103C8T6核心板为例，建立一个简单的闪烁LED工程：<code>stm32f103c8HiXwos</code>。</p>
<p>以下说明对Windows系统和Ubuntu系统都是通用的。</p>
<p><img alt="img" src="../res/figure/stm32f103c8-core-board.png" title="STM32F103C8T6核心板" /></p>
<hr />
<h1 id="1">1.搭建开发环境</h1>
<ul>
<li><a href="../01-Envsetup-Guide/">开发环境搭建指南</a></li>
</ul>
<hr />
<h1 id="2">2.选择模板</h1>
<p>在<code>xwbd</code>文件夹中有一些名字类似于<code>stm32fxxxHiXwos</code>的工程，这些工程只有一个闪烁的LED功能，
可以复制这些工程作为模板。</p>
<hr />
<h1 id="3">3.改名</h1>
<ol>
<li>可将工程文件夹改成自己的工程名称，名称需要符合C语言符号的规则，因为名称会在
    源码中以宏定义的形式出现，<code>-</code>，<code>@</code>等符号会引起语法错误；</li>
<li>打开配置<code>stm32f103c8HiXwos/cfg/XuanWuOS.h</code>，将<code>XuanWuOS_CFG_BOARD</code>的定义
    改成与工程文件夹名称一致；</li>
<li>尝试编译一次，打开终端，把路径切换至<strong>XuanWuOS/xwbd/stm32fxxxHiXwos</strong>，
    在终端中执行make命令。</li>
</ol>
<p><img alt="img" src="../res/figure/stm32f103c8HiXwos-DbgBuildOut.png" title="编译" /></p>
<h1 id="4memory">4.修改memory区域</h1>
<p>打开<code>stm32f103c8HiXwos/cfg/XuanWuOS.lds</code>，此为gcc的ld链接脚本，可以按照单片机的资源情况修改。</p>
<pre><code class="C">/* 内部flash的信息 */
flash_mr_origin = 0x08000000;
flash_mr_size = 64k;

/* 内部RAM的信息 */
ocram_mr_origin = 0x20000000;
ocram_mr_size = 20k;

/* 定义固件的起始地址 */
fmw_origin = DEFINED(fmw)? fmw : flash_mr_origin;

/* 定义存储器信息 */
MEMORY {
        /* 内部flash的信息 */
        flash_mr (rx): org = flash_mr_origin, len = flash_mr_size
        /* 内部RAM的信息 */
        ocram_mr (rwx): org = ocram_mr_origin, len = ocram_mr_size

        /* 中断向量表的加载地址(LMA)区域 */
        vctbl_lmr (rx):
                org = fmw_origin,
                len = 1024

        /* 中断向量表的运行地址(VMA)区域 */
        vctbl_vmr (rw):
                org = fmw_origin,
                len = 1024

        /* 镜像文件的信息 */
        image_description_mr (rx):
                org = ORIGIN(vctbl_lmr) + LENGTH(vctbl_lmr),
                len = 64

        /* 代码段(.text)与只读数据段(.rodata) */
        code_mr (rx):
                org = ORIGIN(image_description_mr) + LENGTH(image_description_mr),
                len = flash_mr_size - LENGTH(image_description_mr) - LENGTH(vctbl_lmr)

        /* 数据段(.data)与未初始化的数据段(.bss) */
        data_mr (arw):
                org = data_mr_origin,
                len = 18k

        /* 玄武OS的内核栈 */
        xwos_stk_mr (rw):
                org = ORIGIN(data_mr) + LENGTH(data_mr),
                len = ocram_mr_size - LENGTH(data_mr)
}

/* 引入链接规则 */
INCLUDE f1.lds
</code></pre>

<h2 id="41ld">4.1.ld的基本语法</h2>
<h3 id="_2">定义存储器区域</h3>
<pre><code class="C">名字 (属性): org = xxx, len = xxx
</code></pre>

<ul>
<li><code>org</code>: 表示定义存储器的起始地址，可以缩写为o</li>
<li><code>len</code>: 表示定义存储器长度，可以缩写为l</li>
<li><code>ORIGIN(x)</code>: 表示取存储器x的起始地址</li>
<li><code>LENGTH(x)</code>: 表示取存储器x的长度</li>
<li>属性: <code>r</code>表示读，<code>w</code>表示写，<code>a</code>表示可申请，<code>x</code>表示可执行</li>
</ul>
<h3 id="vctbl_lmr-vctbl_vmr"><code>vctbl_lmr</code> &amp; <code>vctbl_vmr</code></h3>
<p>玄武OS的中断向量表区域，其中<strong>LMR</strong>表示中断向量的加载地址区域，
也即是中断向量在Flash中的存储位置，VMR表示中断向量的运行地址区域，
也即是上电运行时的中断向量的地址。</p>
<ul>
<li>如果<strong>LMR</strong>与<strong>VMR</strong>都指向Flash，且起始地址(org)与大小(len)完全一致，表示加载地址
    就是运行地址，玄武OS在初始化阶段不会对中断向量执行拷贝操作；</li>
<li>如果<strong>VMR</strong>指向RAM的某个地址，玄武OS会在初始化阶段把Flash中的中断向量表拷贝到
    <strong>VMR</strong>指定的RAM内，并设置ARM的VTOR寄存器；</li>
<li>需要注意ARM的VTOR寄存器低7位(0~6)必须保持为0，因此VMR的起始地址也必须满足
    此规则。</li>
</ul>
<h3 id="image_description_mr"><code>image_description_mr</code></h3>
<p>此段中包含镜像文件的一些基本信息，例如起始位置，结尾标志位置等，可用在升级固件功能中。</p>
<h3 id="code_mr"><code>code_mr</code></h3>
<p>存放代码和常量的地方。此处让ld自动计算大小，把剩余flash空间全部放在此段。</p>
<h3 id="data_mr"><code>data_mr</code></h3>
<p>存放全局变量、静态变量的地方。此处分配了17K字节的内存。连接器ld安排完全局变量、
静态变量后的剩余的部分，玄武OS会全部交给<strong>默认的内核内存分配器</strong>，
用于为动态创建内核对象的API提供底层接口。</p>
<h3 id="xwos_stk_mr"><code>xwos_stk_mr</code></h3>
<p>玄武OS内核的栈内存，玄武OS内核处理中断时会使用此内存作为函数的栈。
此处也让ld自动计算大小，把剩余内存全部放在此处。</p>
<hr />
<h1 id="5stm32cubemx">5.STM32CubeMX</h1>
<h2 id="51stm32cubemx">5.1.导入STM32CubeMX工程</h2>
<p>已经配置好的工程<code>xwbd/stm32f103c8HiXwos/bm/stm32cube/cubemx/stm32f103c8HiXwos.ioc</code>
可通过STM32CubeMX直接打开。</p>
<h2 id="52">5.2.设置</h2>
<h3 id="nvic">NVIC设置</h3>
<ul>
<li>设置3个抢占优先级位和1个子优先级位</li>
<li>SVC中断设置成<strong>最高</strong>优先级</li>
<li>PendSV中断设置成<strong>最低</strong>优先级</li>
<li>Systick中断设置成<strong>最低</strong>优先级</li>
</ul>
<p><img alt="img" src="../res/figure/STM32F103C8-CubeMX-NVIC.png" title="NVIC设置" /></p>
<h3 id="_3">工程设置</h3>
<p><img alt="img" src="../res/figure/STM32F103C8-CubeMX-ProjectManager.png" title="工程设置" /></p>
<ul>
<li>需要指定<code>toolchain/IDE</code>为<code>Makefile</code>；</li>
<li>需要指定源码生成的目录为<code>XuanWuOS/xwbd/stm32f103c8HiXwos/bm/stm32cube/cubemx</code>；</li>
</ul>
<h2 id="53">5.3.生成源码</h2>
<p>点击STM32CubeMX中的生成源码按钮后，可以获得下面的内容：</p>
<p><img alt="img" src="../res/figure/STM32F103C8-CubeMX-GeneratedCode.png" title="生成的源码" /></p>
<p>玄武OS不使用STM32CubeMX生成的启动代码，需要重新定义中断向量表，玄武OS的编译系统中
提供了一个脚本可以自动生成中断向量表的代码：</p>
<pre><code class="shell">xwbs/util/el/stm32ivt/stm32ivt.el xwbd/stm32f103HiXwos/bm/stm32cube
</code></pre>

<p>脚本执行完成后，会生成名为<code>IVT</code>的文件夹，需要注意脚本指定的路径为<code>cubemx</code>的
父目录。</p>
<h2 id="54">5.4.集成</h2>
<p>stm32cube的源代码使用<strong>玄武模块</strong>的形式与玄武OS进行集成。
cubemx目录的上一级为<strong>stm32cube模块</strong>的根目录。</p>
<p><img alt="img" src="../res/figure/STM32F103C8-CubeMX-Xwmo.png" title="stm32cube模块" /></p>
<h3 id="cubemx">cubemx</h3>
<p>前文中已经描述过，此为STM32CubeMX生成的代码。</p>
<h3 id="xwmomk">xwmo.mk</h3>
<p>编译规则，玄武模块设计思路与Android.mk类似，需要将源码文件、
编译选项、头文件路径等列举在此文件中。
详细可以参考<a href="../../../UserManual/03-Build-System/">应用手册-构建系统</a></p>
<h3 id="standardh">standard.h</h3>
<p>此为顶级头文件，所有源码都需要包含此文件。</p>
<h3 id="mifcmifh">mif.c/mif.h</h3>
<p>模块接口（<strong>Module InterFace</strong>），其中
包含两个重要的函数：<code>stm32cube_lowlevel_init()</code>与<code>stm32cube_init()</code>。
在低级初始化流程中，<code>stm32cube_lowlevel_init()</code>被<code>board_lowlevel_init()</code>调用。
在初始化流程中，<code>stm32cube_init()</code>被<code>board_init()</code>调用。</p>
<p>玄武OS不使用STM32CubeMX生成的启动代码，但需要调用其启动代码中的某些函数
完成对芯片的初始化，这些函数分别被<code>stm32cube_lowlevel_init()</code>与<code>stm32cube_init()</code>调用。</p>
<h3 id="xwac">xwac</h3>
<p>此文件夹的源文件为玄武OS的适配代码。</p>
<ol>
<li>
<p>xwlib/crc32.c</p>
<p>此源文件为玄武C库中的<code>xwos/lib/crc32.c</code>提供底层接口。</p>
</li>
<li>
<p>xwos/hook.c</p>
<p>此源文件提供函数<code>stm32cube_systick_hook()</code>，此函数被玄武OS的systick中断调用，
使得HAL库中的Tick计数器也一起增加。如果没有此函数，HAL库中的延时函数
将不能正常工作。</p>
</li>
</ol>
<h3 id="mainc">main.c</h3>
<p>用户应用入口函数<code>xwos_main()</code>定义在此源文件中，此函数为玄武OS初始化流程的最后一个
函数，详细可参考<a href="../../../UserManual/04-Boot-Flow/">应用手册-启动流程</a>。</p>
<h2 id="55">5.5.编译</h2>
<p>打开<code>xwbd/stm32f103c8HiXwos/cfg/board.h</code>，增加宏定义：</p>
<pre><code class="C">#define BMCFG_stm32cube  1
</code></pre>

<p>此宏为玄武模块stm32cube的编译开关。</p>
<p>如果需要编译Release版本的bin文件，可以在编译时增加选项~D=0，Release编译时会开启编译器的优化选项。</p>
<p><img alt="img" src="../res/figure/stm32f103c8HiXwos-RlsBuildOut.png" title="Release编译" /></p>
<p>产生的bin文件的大小将大大减少，但不利于调试器调试代码。</p>
<p><img alt="img" src="../res/figure/stm32f103c8HiXwos-RlsBuildOut.png" title="Release编译结果" /></p>
<hr />
<h1 id="6stm32cubeide">6.使用STM32CubeIDE进行开发</h1>
<h2 id="61eclipse">6.1.Eclipse设置</h2>
<h3 id="_4">设置代码缩进（参考）</h3>
<p>菜单 <strong>Window &#x2013;&gt; Preferences</strong></p>
<p><img alt="img" src="../res/figure/Window-Preferences-General-Editors-TextEditors.png" title="设置代码缩进" /></p>
<h3 id="_5">设置文件保存时自动删除行尾空白字符（参考）</h3>
<p>菜单 <strong>Window &#x2013;&gt; Preferences</strong></p>
<p><img alt="img" src="../res/figure/Window-Preferences-C-Editors-SaveActions.png" title="设置自动删除行尾空白字符" /></p>
<h3 id="xuanwuoscode-style">XuanWuOS的Code Style配置文件（参考）</h3>
<p>通过“<strong>右键另存为</strong>”下载：</p>
<ul>
<li><a href="../res/XuanWuOS-C-CodeStyle.xml">C</a></li>
<li><a href="../res/XuanWuOS-CPP-CodeStyle.xml">C++</a></li>
</ul>
<p>可从菜单
<strong>Window &#x2013;&gt; Preferences &#x2013;&gt; C/C++ -&gt; Code Style -&gt; Formatter -&gt; Import&#x2026;</strong>
导入。</p>
<h2 id="62">6.2.新建工程</h2>
<ol>
<li>在IDE的工作目录中建立一个文件夹：<code>stm32f103c8HiXwos</code>；</li>
<li>将文件<code>XuanWuOS/xwbd/stm32f103c8HiXwos/bm/stm32cube/cubemx/stm32f103c8HiXwos.ioc</code>
拷贝至这个文件夹中；</li>
<li>将<code>XuanWuOS</code>文件夹也拷贝到此文件夹中。</li>
</ol>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Project-Dir.png" title="工程目录结构" /></p>
<p>选择菜单"<strong>File&#x2013;&gt;New&#x2013;&gt;STM32 Project from STM32CubeMX .ioc File</strong>"</p>
<p><img alt="img" src="../res/figure/STM32CubeIDE-New-Project.png" title="新建工程" /></p>
<p>STM32CubeMX会自动生成代码：<code>Core</code>、<code>Drivers</code>、<code>STM32F103C8TX_FLASH.ld</code>，
这些代码都没有用，可以删除。</p>
<h2 id="63">6.3.文件编码设置</h2>
<ul>
<li>菜单 <strong>Project &#x2013;&gt; Properties &#x2013;&gt; Resource</strong></li>
</ul>
<p><img alt="img" src="../res/figure/Project-Properties-Resource.png" title="文件编码设置" /></p>
<h2 id="64">6.4.编译设置</h2>
<ul>
<li>菜单 <strong>Project &#x2013;&gt; Properties</strong></li>
<li><strong>Debug</strong>和<strong>Release</strong>两个配置都需要增加：</li>
</ul>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Project-Properties-C-Build-Path.png" title="编译路径设置" /></p>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Project-Properties-C-Build-Behavior.png" title="编译目标设置" /></p>
<h2 id="65">6.5.环境变量设置</h2>
<ul>
<li>菜单<strong>Project &#x2013;&gt; Properties &#x2013;&gt; C/C++ Build &#x2013;&gt; Environment</strong></li>
<li>设置<ul>
<li><strong>WKSPC</strong>: <strong>../../../${ConfigName}</strong></li>
<li><strong>~V</strong>: <strong>1</strong></li>
<li><strong>~D</strong>: <strong>Debug</strong>配置为<strong>1</strong>，<strong>Release</strong>配置为<strong>0</strong></li>
</ul>
</li>
<li><strong>Debug</strong>和<strong>Release</strong>两个配置都需要增加：</li>
</ul>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Project-Properties-C-Build-Env-Debug.png" title="Debug配置" /></p>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Project-Properties-C-Build-Env-Release.png" title="Release配置" /></p>
<h3 id="gnu-mcu-eclipse">设置工具链为<a href="https://gnu-mcu-eclipse.github.io/downloads/">GNU MCU Eclipse</a>提供的工具链</h3>
<ul>
<li>参考<a href="../01-Envsetup-Guide/">《Ubuntu &amp; Windows 开发环境搭建指南》</a>安装工具；</li>
<li>修改Debug和Release两个配置的<strong>PATH</strong>环境变量<ul>
<li>将包含gnumcu目录的路径放在前面，保证最先被搜索；</li>
<li>删除包含STM32CubeIDE目录的所有路径。</li>
</ul>
</li>
</ul>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Properties-C-Build-Env-Path-Linux.png" title="Env-PATH" /></p>
<h2 id="66">6.6.头文件路径设置</h2>
<p>头文件路径只影响Eclipse中代码的跳转，可打开菜单
<strong>Project &#x2013;&gt; Properties &#x2013;&gt; C/C++ General &#x2013;&gt; Paths and Symbols</strong>
增加头文件路径。</p>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Project-Properties-C-Path-Symbols.png" title="头文件路径" /></p>
<h2 id="67">6.7.调试</h2>
<h3 id="_6">先编译一次工程</h3>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Build.png" title="编译" /></p>
<h3 id="openocddaplink">使用OpenOCD+DAPLink进行调试</h3>
<ul>
<li>打开菜单 <strong>Run &#x2013;&gt; Debug Configurations&#x2026;</strong> ，双击 <strong>GBD OpenOCD Debugging</strong>
    建立新的设置；</li>
<li>图中的命令已经在环境变量PATH中，如果无法找命令，则需要写出完整路径。
    如果读者参考了之前的指南搭建开发环境，这些命令应该可被找到。</li>
</ul>
<p><img alt="img" src="../res/figure/DAPLink-Debug-Configurations-Main.png" title="openocd-Main选择卡设置" /></p>
<p><img alt="img" src="../res/figure/DAPLink-Debug-Configurations-Debugger.png" title="openocd-Debugger选择卡设置" /></p>
<p><img alt="img" src="../res/figure/DAPLink-Debug-Configurations-Startup.png" title="openocd-Startup选择卡设置" /></p>
<h3 id="stlink">使用STLink进行调试</h3>
<ul>
<li>打开菜单 <strong>Run &#x2013;&gt; Debug Configurations&#x2026;</strong> ，双击
    <strong>STM32 Cortext-M C/C++ Application</strong> 建立新的设置；</li>
<li>图中的命令已经在环境变量PATH中，如果无法找命令，则需要写出完整路径。
    如果读者参考了之前的指南搭建开发环境，这些命令应该可被找到。</li>
</ul>
<p><img alt="img" src="../res/figure/STLink-Debug-Configurations-Main.png" title="STLink-Main选择卡设置" /></p>
<p><img alt="img" src="../res/figure/STLink-Debug-Configurations-Debugger.png" title="STLink-Debugger选择卡设置" /></p>
<p><img alt="img" src="../res/figure/STLink-Debug-Configurations-Startup.png" title="STLink-Startup选择卡设置" /></p>
<h3 id="_7">开始调试</h3>
<p><img alt="img" src="../res/figure/STM32CubeIDE-Debugging.png" title="调试过程" /></p>
<h3 id="_8">复位调试</h3>
<p>如果调试过程中没有找到复位按钮，可以采用如下方法处理：</p>
<ul>
<li>在程序入口处设置一个断点；</li>
<li>然后让程序全速运行；</li>
<li>按一下复位按键，程序应该会停在入口的断点处。</li>
</ul>
<hr />
<h1 id="7">7.代码启动流程</h1>
<p><img alt="img" src="../res/figure/stm32-boot-flow.png" title="STM32启动流程" /></p>
<ul>
<li><code>stm32cube_lowlevel_init()</code>：初始化时钟</li>
<li><code>stm32cube_init()</code>：初始化内存管理、cache、GPIO、DMA等基础设备</li>
<li><code>xwos_main()</code>：用户应用入口函数</li>
</ul>
<hr />
<h1 id="8">8.使用命令行方式进行开发</h1>
<h2 id="81">8.1.编译</h2>
<h3 id="release">编译Release版本</h3>
<pre><code class="sh">cd  xwbd/stm32f103c8HiXwos
make ~D=0 -j8
</code></pre>

<h3 id="debug">编译Debug版本</h3>
<pre><code class="sh">cd xwbd/stm32f103c8HiXwos
make -j8
</code></pre>

<h3 id="_9">查看完整的编译过程</h3>
<pre><code class="sh">cd xwbd/stm32f103c8HiXwos
make ~V=1 -j8
</code></pre>

<h2 id="82">8.2.调试</h2>
<h3 id="openocd">启动openocd服务</h3>
<p>连接好调试器，打开终端，输入下列命令启动openocd</p>
<pre><code class="sh">cd xwbd/stm32f103c8HiXwos
make cmdap
</code></pre>

<h3 id="gdb">启动gdb</h3>
<h4 id="flash">擦除Flash</h4>
<p>打开另外一个终端，输入下面命令</p>
<pre><code class="sh">cd xwbd/stm32f103c8HiXwos
make erase
</code></pre>

<p>擦除完成，将进入到gdb的交互终端，可使用命令 <strong>q</strong> 退出。</p>
<h4 id="flash_1">烧写Flash</h4>
<pre><code class="sh">cd xwbd/stm32f103c8HiXwos
make pgm
</code></pre>

<p>烧写完成，将进入到gdb的交互终端，可直接开始调试。</p>
<h4 id="_10">直接启动调试</h4>
<pre><code class="sh">cd xwbd/stm32f103c8HiXwos
make dbg
</code></pre>

<p><img alt="img" src="../res/figure/Terminal-Debugging.png" title="终端调试过程" /></p>
<h3 id="gdb_1">常用gdb命令</h3>
<pre><code class="sh">mon reset init          # 复位（如果使用SWD方式，需要在执行前按住复位按键，
                        #       然后输入这条命令，敲击回车后再释放复位按键。
                        #       JTAG方式则不需要）
mon reset halt          # 复位并挂起
mon soft_reset_halt     # 软复位（此命令已被废弃，较新的MCU可能不支持）
l path/file.c:n         # 列举源码文件path/file.c的第n行
l func                  # 列举函数func的源码
l                       # 继续列举断点处的剩余源码
b path/file.c:n         # 在path/file.c的第n行设置一个断点
b func                  # 在函数func()入口设置一个断点
i b                     # 列举所有断点信息
del x                   # 删除编号为x的断点
n                       # 单步执行
s                       # 单步执行（和上一条命令等价）
si                      # 指令级别的单步执行
ni                      # 指令级别的单步执行（和上一条命令等价）
c                       # 继续执行，直到遇到断点
mon reg                 # 显示所有寄存器
mon reg x               # 显示寄存器x的内容
disassemble             # 反汇编当前PC指针处的代码
disassemble func        # 反汇编函数func()的代码
disassemble 0xXXXX      # 反汇地址0xXXXXXXXX处的代码
q                       # 退出gdb
</code></pre>

<hr />
<h1 id="8_1">8.附录</h1>
<ul>
<li>上一篇 <a href="../01-Envsetup-Guide/">开发环境搭建指南</a></li>
<li>选择一个开发板继续：<ul>
<li><a href="../03-atkh743/">正点原子阿波罗H743开发板</a></li>
<li><a href="../04-fk429m/">反客F429核心板</a></li>
<li><a href="../05-atkf407core/">正点原子F407核心板</a></li>
<li><a href="../06-atkf103core/">正点原子F103核心板</a></li>
</ul>
</li>
</ul></div>
            </div>
        </div>

        <footer class="col-md-12">
            <hr>
            <p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
        </footer>
        <script>
            var base_url = "../../..",
                shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
        </script>
        <script src="../../../js/base.js" defer></script>
        <script src="../../../search/main.js" defer></script>

        <div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="searchModalLabel">搜索</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
                <p>
                    在这里所有文档：
                </p>
                <form>
                    <div class="form-group">
                        <input type="search" class="form-control" placeholder="搜索..." id="mkdocs-search-query" title="Type search term here">
                    </div>
                </form>
                <div id="mkdocs-search-results"></div>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
              <table class="table">
                <thead>
                  <tr>
                    <th style="width: 20%;">Keys</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td class="help shortcut"><kbd>?</kbd></td>
                    <td>Open this help</td>
                  </tr>
                  <tr>
                    <td class="next shortcut"><kbd>n</kbd></td>
                    <td>Next page</td>
                  </tr>
                  <tr>
                    <td class="prev shortcut"><kbd>p</kbd></td>
                    <td>Previous page</td>
                  </tr>
                  <tr>
                    <td class="search shortcut"><kbd>s</kbd></td>
                    <td>Search</td>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div>

    </body>
</html>
